package com.koro.aspect;

import com.koro.annotation.NoRepeatSubmit;
import com.koro.cache.RedisService;
import com.koro.constant.Constant;
import com.koro.tool.StringUtils;
import com.koro.vo.BaseException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @Description 防止重复提交标记注解
 */
@Aspect
@Component
public class NoRepeatSubmitAspect {

    @Autowired
    private RedisService redisService;

    @Pointcut("@annotation(com.koro.annotation.NoRepeatSubmit)")
    public void NoRepeatSubmitPointCut() {
    }

    @Around("NoRepeatSubmitPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
        HttpServletRequest request = attributes.getRequest();
        String key = sessionId + "-" + request.getServletPath();
        String token = getRequestToken(request);
        if (StringUtils.isNotBlank(token)) {
            key = token + "-" + request.getServletPath();
        }
        Method method = ((MethodSignature) point.getSignature()).getMethod();
        // 获取RedisCache注解
        NoRepeatSubmit noRepeatSubmit = method.getAnnotation(NoRepeatSubmit.class);
        if (!redisService.exists(key)) {// 如果缓存中有这个url视为重复提交
            Object o = point.proceed();
            redisService.set(key, 0, noRepeatSubmit.expired());
            return o;
        } else {
            throw new BaseException("请勿频繁提交数据!");
        }
    }

    /**
     * 获取请求的token
     */
    private String getRequestToken(HttpServletRequest httpRequest) {
        //从header中获取token
        String token = httpRequest.getHeader(Constant.HEADER);
        //如果header中不存在token，则从参数中获取token
        if (StringUtils.isBlank(token)) {
            token = httpRequest.getParameter(Constant.HEADER);
        }
        return token;
    }
}
